﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;
using CARE;
using CARE.GraphML;

namespace CARE
{
    public partial class SpreadVizualization : Page, IWizardButtonController
    {
        private Source networkSource;
        private DiseaseSelector diseaseSource;
        private SetupSimulation setup;
        private SimulationVisualization simulation;
        private int currentPage = 0;
        private static Dictionary<String, SolidColorBrush> statesColors = new Dictionary<string, SolidColorBrush>();

        public SetupSimulation Setup
        {
            get { return setup; }
            set { setup = value; }
        }

        public SpreadVizualization()
        {
            InitializeComponent();

            networkSource = new Source(this);
            wizard.Pages.Add(networkSource);
            diseaseSource = new DiseaseSelector(this);
            wizard.Pages.Add(diseaseSource);
            Setup = new SetupSimulation(this);
            wizard.Pages.Add(Setup);
            simulation = new SimulationVisualization(this);
            wizard.Pages.Add(simulation);

            DisableNext();
            wizard.PageEvent += new WizardPageEvent(WizardMenu_PageEvent);
        }

        // Executes when the user navigates to this page.
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
        }

        #region IWizardButtonController Members

        public void EnableNext()
        {
            if (currentPage == 1)
                diseaseSource_isSelectedDisease();
            wizard.btNext.IsEnabled = true;
        }

        public void DisableNext()
        {
            wizard.btNext.IsEnabled = false;
        }

        #endregion

        public static SolidColorBrush GetColorForDisease(String Disease)
        {
            if (statesColors.ContainsKey(Disease))
                return statesColors[Disease];
            else
                return new SolidColorBrush(Colors.Transparent);
        }

        public String[] GetAvailableStates()
        {
            return statesColors.Keys.ToArray();
        }

        private void WizardMenu_PageEvent(Wizard sender, WizardEventArgs e)
        {
            currentPage = e.NewPageIndex;

            if (e.Action == WizardAction.Finish || e.Action == WizardAction.Exit)
            {
                DisableNext();
                wizard.btNext.Content = "Next";
                wizard.ctrPageHost.SwitchPage(wizard.Pages[0]);
            }
            else if (e.NewPageIndex == 0) // Network source
                DisableNext();
            else if (e.NewPageIndex == 1)
            { // Disease source
                DisableNext();
                statesColors.Clear();
            }
            else if (e.NewPageIndex == 2)
            { // Setup
                //setup.Init();
                EnableNext();
            }
            else if (e.NewPageIndex == 3) // Simulation
            {
                simulation.Init();
            }  //simulation.Init();
            else if (e.NewPageIndex == 4) // Report
            { }  //report.Init();
        }

        private void diseaseSource_isSelectedDisease()
        {
            statesColors.Clear();
            if (SimulationParameters.getInstance().DiseaseGraph != null)
            {
                foreach (var item in SimulationParameters.getInstance().DiseaseGraph.Vertices)
                {
                    SolidColorBrush c = new SolidColorBrush(Colors.Transparent);
                    foreach (var color in item.Keys)
                    {
                        if (color.Key == "nodeColor")
                        {
                            try
                            {
                                c = new SolidColorBrush(HexColor(color.Value));
                            }
                            catch (Exception)
                            {
                                c = new SolidColorBrush((Color)(typeof(Colors)).GetProperty(color.Value).GetValue(null, null));
                            }
                        }
                        if (color.Key == "stateName")
                        {
                            c.Opacity = 0.5;
                            statesColors.Add(color.Value, c);
                        }
                    }
                }
            }
            else
            {
                System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(typeof(graphml));
                System.IO.StringReader reader = new System.IO.StringReader(SimulationParameters.getInstance().DiseaseGraphML);
                var graph = (graphml)ser.Deserialize(reader);

                foreach (var item in graph.graph.node)
                {
                    SolidColorBrush c = new SolidColorBrush(Colors.Transparent);
                    foreach (var color in item.data)
                    {
                        if (color.key == "nodeColor")
                        {
                            try
                            {
                                c = new SolidColorBrush(HexColor(color.Value));
                            }
                            catch (Exception)
                            {
                                c = new SolidColorBrush((Color)(typeof(Colors)).GetProperty(color.Value).GetValue(null, null));
                            }
                        }
                    }
                    c.Opacity = 0.5;
                    statesColors.Add(item.id, c);
                }
            }
        }

        private Color HexColor(String hex)
        {
            //remove the # at the front
            hex = hex.Replace("#", "");

            byte a = 255;
            byte r = 255;
            byte g = 255;
            byte b = 255;

            int start = 0;

            //handle ARGB strings (8 characters long)
            if (hex.Length == 8)
            {
                a = byte.Parse(hex.Substring(0, 2), System.Globalization.NumberStyles.HexNumber);
                start = 2;
            }

            //convert RGB characters to bytes
            r = byte.Parse(hex.Substring(start, 2), System.Globalization.NumberStyles.HexNumber);
            g = byte.Parse(hex.Substring(start + 2, 2), System.Globalization.NumberStyles.HexNumber);
            b = byte.Parse(hex.Substring(start + 4, 2), System.Globalization.NumberStyles.HexNumber);

            return Color.FromArgb(a, r, g, b);
        }
    }
}
